package com.x.attendance.assemble.control.service;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;

import com.x.attendance.core.entity.AttendanceRecord;
import com.x.base.core.project.logger.Logger;
import com.x.base.core.project.logger.LoggerFactory;

/**
 * 中控U160考勤设备服务
 * @author Manus AI
 */
public class AttendanceDeviceService {

	private static Logger logger = LoggerFactory.getLogger(AttendanceDeviceService.class);
	
	private Socket socket;
	private OutputStream outputStream;
	private InputStream inputStream;
	private boolean connected = false;
	
	// 中控设备通信协议常量
	private static final byte[] CMD_CONNECT = {0x01, 0x00, 0x00, 0x00};
	private static final byte[] CMD_DISCONNECT = {0x02, 0x00, 0x00, 0x00};
	private static final byte[] CMD_UPLOAD_FINGERPRINT = {0x03, 0x00, 0x00, 0x00};
	private static final byte[] CMD_UPLOAD_PHOTO = {0x04, 0x00, 0x00, 0x00};
	private static final byte[] CMD_DOWNLOAD_RECORDS = {0x05, 0x00, 0x00, 0x00};
	private static final byte[] CMD_RESTART_DEVICE = {0x06, 0x00, 0x00, 0x00};

	/**
	 * 连接设备
	 */
	public boolean connectDevice(String ipAddress, int port) {
		try {
			if (connected) {
				disconnect();
			}
			
			socket = new Socket(ipAddress, port);
			socket.setSoTimeout(30000); // 30秒超时
			
			outputStream = socket.getOutputStream();
			inputStream = socket.getInputStream();
			
			// 发送连接命令
			sendCommand(CMD_CONNECT);
			byte[] response = receiveResponse();
			
			if (isSuccessResponse(response)) {
				connected = true;
				logger.info("设备连接成功: {}:{}", ipAddress, port);
				return true;
			} else {
				logger.error("设备连接失败: {}:{}", ipAddress, port);
				closeSocket();
				return false;
			}
		} catch (Exception e) {
			logger.error("连接设备异常: " + ipAddress + ":" + port, e);
			closeSocket();
			return false;
		}
	}

	/**
	 * 上传指纹模板
	 */
	public boolean uploadFingerprint(String employeeId, byte[] template) {
		if (!connected) {
			logger.error("设备未连接");
			return false;
		}
		
		try {
			// 构造指纹上传数据包
			byte[] packet = buildFingerprintPacket(employeeId, template);
			
			// 发送上传指纹命令
			sendCommand(CMD_UPLOAD_FINGERPRINT);
			sendData(packet);
			
			byte[] response = receiveResponse();
			boolean success = isSuccessResponse(response);
			
			if (success) {
				logger.info("指纹上传成功: 员工ID={}", employeeId);
			} else {
				logger.error("指纹上传失败: 员工ID={}", employeeId);
			}
			
			return success;
		} catch (Exception e) {
			logger.error("上传指纹异常: 员工ID=" + employeeId, e);
			return false;
		}
	}

	/**
	 * 上传员工照片
	 */
	public boolean uploadPhoto(String employeeId, byte[] photo) {
		if (!connected) {
			logger.error("设备未连接");
			return false;
		}
		
		try {
			// 构造照片上传数据包
			byte[] packet = buildPhotoPacket(employeeId, photo);
			
			// 发送上传照片命令
			sendCommand(CMD_UPLOAD_PHOTO);
			sendData(packet);
			
			byte[] response = receiveResponse();
			boolean success = isSuccessResponse(response);
			
			if (success) {
				logger.info("照片上传成功: 员工ID={}", employeeId);
			} else {
				logger.error("照片上传失败: 员工ID={}", employeeId);
			}
			
			return success;
		} catch (Exception e) {
			logger.error("上传照片异常: 员工ID=" + employeeId, e);
			return false;
		}
	}

	/**
	 * 下载考勤记录
	 */
	public List<AttendanceRecord> downloadRecords() {
		List<AttendanceRecord> records = new ArrayList<>();
		
		if (!connected) {
			logger.error("设备未连接");
			return records;
		}
		
		try {
			// 发送下载记录命令
			sendCommand(CMD_DOWNLOAD_RECORDS);
			
			byte[] response = receiveResponse();
			if (isSuccessResponse(response)) {
				// 解析考勤记录数据
				records = parseAttendanceRecords(response);
				logger.info("下载考勤记录成功: 记录数={}", records.size());
			} else {
				logger.error("下载考勤记录失败");
			}
		} catch (Exception e) {
			logger.error("下载考勤记录异常", e);
		}
		
		return records;
	}

	/**
	 * 重启设备
	 */
	public boolean restartDevice() {
		if (!connected) {
			logger.error("设备未连接");
			return false;
		}
		
		try {
			// 发送重启命令
			sendCommand(CMD_RESTART_DEVICE);
			
			byte[] response = receiveResponse();
			boolean success = isSuccessResponse(response);
			
			if (success) {
				logger.info("设备重启命令发送成功");
			} else {
				logger.error("设备重启命令发送失败");
			}
			
			return success;
		} catch (Exception e) {
			logger.error("重启设备异常", e);
			return false;
		}
	}

	/**
	 * 断开连接
	 */
	public void disconnect() {
		if (connected) {
			try {
				sendCommand(CMD_DISCONNECT);
			} catch (Exception e) {
				logger.warn("发送断开连接命令失败", e);
			}
		}
		
		closeSocket();
		connected = false;
		logger.info("设备连接已断开");
	}

	/**
	 * 发送命令
	 */
	private void sendCommand(byte[] command) throws IOException {
		outputStream.write(command);
		outputStream.flush();
	}

	/**
	 * 发送数据
	 */
	private void sendData(byte[] data) throws IOException {
		// 先发送数据长度
		byte[] lengthBytes = intToBytes(data.length);
		outputStream.write(lengthBytes);
		
		// 再发送数据内容
		outputStream.write(data);
		outputStream.flush();
	}

	/**
	 * 接收响应
	 */
	private byte[] receiveResponse() throws IOException {
		// 先读取响应长度
		byte[] lengthBytes = new byte[4];
		inputStream.read(lengthBytes);
		int length = bytesToInt(lengthBytes);
		
		// 再读取响应内容
		byte[] response = new byte[length];
		int totalRead = 0;
		while (totalRead < length) {
			int read = inputStream.read(response, totalRead, length - totalRead);
			if (read == -1) {
				throw new IOException("连接已断开");
			}
			totalRead += read;
		}
		
		return response;
	}

	/**
	 * 检查响应是否成功
	 */
	private boolean isSuccessResponse(byte[] response) {
		return response != null && response.length > 0 && response[0] == 0x00;
	}

	/**
	 * 构造指纹数据包
	 */
	private byte[] buildFingerprintPacket(String employeeId, byte[] template) {
		// 简化的数据包格式：员工ID(32字节) + 指纹模板(2048字节)
		byte[] packet = new byte[32 + 2048];
		
		// 填充员工ID
		byte[] idBytes = employeeId.getBytes();
		System.arraycopy(idBytes, 0, packet, 0, Math.min(idBytes.length, 32));
		
		// 填充指纹模板
		System.arraycopy(template, 0, packet, 32, Math.min(template.length, 2048));
		
		return packet;
	}

	/**
	 * 构造照片数据包
	 */
	private byte[] buildPhotoPacket(String employeeId, byte[] photo) {
		// 简化的数据包格式：员工ID(32字节) + 照片大小(4字节) + 照片数据
		byte[] packet = new byte[32 + 4 + photo.length];
		
		// 填充员工ID
		byte[] idBytes = employeeId.getBytes();
		System.arraycopy(idBytes, 0, packet, 0, Math.min(idBytes.length, 32));
		
		// 填充照片大小
		byte[] sizeBytes = intToBytes(photo.length);
		System.arraycopy(sizeBytes, 0, packet, 32, 4);
		
		// 填充照片数据
		System.arraycopy(photo, 0, packet, 36, photo.length);
		
		return packet;
	}

	/**
	 * 解析考勤记录
	 */
	private List<AttendanceRecord> parseAttendanceRecords(byte[] data) {
		List<AttendanceRecord> records = new ArrayList<>();
		
		// 简化的解析逻辑，实际需要根据设备协议实现
		// 这里只是示例代码
		
		return records;
	}

	/**
	 * 关闭Socket连接
	 */
	private void closeSocket() {
		try {
			if (outputStream != null) {
				outputStream.close();
			}
			if (inputStream != null) {
				inputStream.close();
			}
			if (socket != null) {
				socket.close();
			}
		} catch (IOException e) {
			logger.warn("关闭Socket连接异常", e);
		}
	}

	/**
	 * 整数转字节数组
	 */
	private byte[] intToBytes(int value) {
		return new byte[] {
			(byte) (value & 0xFF),
			(byte) ((value >> 8) & 0xFF),
			(byte) ((value >> 16) & 0xFF),
			(byte) ((value >> 24) & 0xFF)
		};
	}

	/**
	 * 字节数组转整数
	 */
	private int bytesToInt(byte[] bytes) {
		return (bytes[0] & 0xFF) |
			   ((bytes[1] & 0xFF) << 8) |
			   ((bytes[2] & 0xFF) << 16) |
			   ((bytes[3] & 0xFF) << 24);
	}
}

